package cc.rengu.igas.share.core.service.channel.momp;

import cc.rengu.igas.momp.facade.base.Header;
import cc.rengu.igas.momp.facade.request.ComboMchntFeeDiscountReversalRequest;
import cc.rengu.igas.momp.facade.request.ComboPaymentRequest;
import cc.rengu.igas.momp.facade.response.ComboMchntFeeDiscountReversalResponse;
import cc.rengu.igas.momp.facade.result.Result;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.ShareServiceConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.enums.ChannelCallModeEnum;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.utility.util.GlobalTransUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;

import java.util.Optional;

/**
 * 混合支付冲正(商户手续费优惠)
 * Created by wangcheng on 2021/3/23 18:00
 */
public class ComboMchntFeeDiscountReversalService extends ChannelBaseService {
    @Override
    public Object callPreProc(TxnInfo txnInfo, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /* Step3：业务请求头 */
        Header header = new Header();
        header.setInstId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID));
        header.setChanlId(ChannelEnum.OPMS.getChannelType());
        header.setSrcSysId(AppParamConstant.SYS_ID);
        header.setBizType(AppParamConstant.DEFAULT_BIZ_TYPE);
        header.setVersion(ShareParamConstant.DUBBO_VSERSION);
        header.setTxnNum(channelCallCfg.getCallChannelTxn());
        header.setTraceNo(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM) + channelCallCfg.getCallIndex());
        header.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        header.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        /* Step4：业务请求体 */
        ComboMchntFeeDiscountReversalRequest comboMchntFeeDiscountReversalRequest = new ComboMchntFeeDiscountReversalRequest();
        comboMchntFeeDiscountReversalRequest.setHeader(header);
        String comboPaymentTraceNo = (String) GlobalTransUtil.getCacheValue(TransCacheConstant.MOMP_ORIG_COMB_PAYMENT_TRACE_NO);
        if (StringUtil.isEmptyOrNull(comboPaymentTraceNo)) {
            comboMchntFeeDiscountReversalRequest.setOrigTraceNo(comboPaymentTraceNo);
            return comboMchntFeeDiscountReversalRequest;
        } else {
            return null;
        }
    }

    @Override
    public PayOrderInfo generatePayOrderInfo(ChannelCallCfg channelCallCfg, OrderInfo orderInfo, Object request) throws Exception {
        return null;
    }

    @Override
    public Object callProc(ChannelCallCfg channelCallCfg, Object request) throws Exception {
        ComboMchntFeeDiscountReversalRequest comboMchntFeeDiscountReversalRequest = (ComboMchntFeeDiscountReversalRequest) request;
        /* Step1：调用营销模块联合营销冲正接口 */
        Result<ComboMchntFeeDiscountReversalResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if (AppParamConstant.YES.equals(channelCallCfg.getSyncCallFlag())) {
            /* Step1.1：异步调用 */
            int iReturnCode;
            int callTimes = 0 == channelCallCfg.getSyncQueryRepeatNum() ? 1 : channelCallCfg.getSyncQueryRepeatNum();
            int gatTime = channelCallCfg.getSyncQueryRepeatTime();
            int gatType = StringUtil.isEmptyOrNull(channelCallCfg.getSyncQueryGapType()) ? 0 : Integer.parseInt(channelCallCfg.getSyncQueryGapType());
            if (ChannelCallModeEnum.LOCAL.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.1.1：异步应用内调用 */
                Class clasz = Class.forName(ShareServiceConstant.MOMP_PAYMENT_SERVICE_INNER_PATH);
                iReturnCode = dubboService.asynCallDubboInnerMethod(clasz, ShareServiceConstant.MOMP_COMBO_MCHNT_FEE_DISCOUNT_REVERSAL_METHOD, comboMchntFeeDiscountReversalRequest, channelCallCfg.getSyncResultServiceName(), callTimes, gatType, gatTime);
            } else if (ChannelCallModeEnum.REMOTE.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.1.2：异步远程调用 */
                iReturnCode = dubboService.asynCallDubboService(ShareServiceConstant.MOMP_PAYMENT_SERVICE, ShareServiceConstant.MOMP_COMBO_MCHNT_FEE_DISCOUNT_REVERSAL_METHOD, comboMchntFeeDiscountReversalRequest, channelCallCfg.getSyncResultServiceName(), callTimes, gatType, gatTime);
            } else {
                rglog.error("不支持的通道服务调用方式:{}，交易拒绝!", channelCallCfg.getChannelCallMode());
                throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR);
            }
            if (0 == iReturnCode) {
                return new BizResponse<>(OltpRpcdEnum.TRANS_SUCCESS.getRespCode(), OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
            } else {
                return new BizResponse<>(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
            }
        } else {
            /* Step1.2：同步调用 */
            if (ChannelCallModeEnum.LOCAL.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.2.1：同步应用内调用 */
                Class clasz = Class.forName(ShareServiceConstant.MOMP_PAYMENT_SERVICE_INNER_PATH);
                callResult = (Result<ComboMchntFeeDiscountReversalResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.MOMP_COMBO_MCHNT_FEE_DISCOUNT_REVERSAL_METHOD, comboMchntFeeDiscountReversalRequest);
            } else if (ChannelCallModeEnum.REMOTE.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.2.2：同步远程调用 */
                callResult = (Result<ComboMchntFeeDiscountReversalResponse>) dubboService.callDubboService(ShareServiceConstant.MOMP_PAYMENT_SERVICE, ShareServiceConstant.MOMP_COMBO_MCHNT_FEE_DISCOUNT_REVERSAL_METHOD, comboMchntFeeDiscountReversalRequest);
            } else {
                rglog.error("不支持的通道服务调用方式:{}，交易拒绝!", channelCallCfg.getChannelCallMode());
                throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR);
            }
        }
        return callResult;
    }

    @Override
    public Object querySyncCallResult(PayOrderInfo payOrderInfo, Object request) {
        return null;
    }

    @Override
    public OrderInfo callResultOrderProc(OrderInfo orderInfo, String payOrderIndex, TransStatusEnum transStatusEnum, Object response) {
        Result<ComboMchntFeeDiscountReversalResponse> callResult = (Result<ComboMchntFeeDiscountReversalResponse>) response;
        Optional<PayOrderInfo> payOrderInfoOpt = orderInfo.getPayOrderInfoList().stream().filter(item -> item.getDstCallIndex().equals(payOrderIndex)).findFirst();
        if (payOrderInfoOpt.isPresent() && null != callResult && null != callResult.getResult()) {
            switch (transStatusEnum) {
                case TRANS_SUCC:
                    rglog.info("调用商户手续费优惠冲正成功：{}", JSON.toJSONString(callResult.getResult()));
                    break;
                case TRANS_TIMEOUT:
                    rglog.info("调用商户手续费优惠冲正超时：{}", JSON.toJSONString(callResult.getResult()));
                    break;
                case SYSTEM_REJECT:
                    rglog.info("调用商户手续费优惠冲正失败：{}", JSON.toJSONString(callResult.getResult()));
                    break;
                default:
                    break;
            }
        }
        return null;
    }
}
